"""
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    created by lane.chang on '28/05/2024'
    comment: 用户意图接口
"""
from fastapi import APIRouter, Request, Body, Query, Depends
from sqlalchemy import func

from config import Config
from project.lib.decorator import api_common, exec_duration
from project.lib.common import Session, get_session
from project.lib.common import Global
from project.lib.validators import generate_validator, DateTimeStr
from project.core.function import json_response
from project.service.intent import IntentService, Product, Service
from project.model.basic import Role, Question
from project.model.chatgpt import Chat

intent_router = APIRouter(prefix='', tags=['Intent'])


@intent_router.post('/intent', summary='用户意图')
@api_common(doc_replace=(('{0}', Config.HTTP_DOC_FIX),))
@exec_duration(add_return=True)
async def get_intent(request: Request,
                     bot_id: Role.enums(fixed=Global.count()) = Body(..., title='数字人id'),
                     user_id: str = Body(Role.UDI.value.user_id, title='用户id'),
                     dev_id: str = Body('dev01', title='设备id'),
                     user_message: str = Body(..., title='用户文本'),
                     hotel_services: list[Service] = Body([], title='酒店服务列表'),
                     hotel_questions: list[Question] = Body([], title='酒店固定问答列表'),
                     health_questions: list[Question] = Body([], title='健康固定问答列表'),
                     health_products: list[Product] = Body([], title='产品列表(睡眠监测)'),
                     health_services: list[Service] = Body([], title='服务列表(睡眠监测)'),
                     session: Session = Depends(get_session)):
    """
    **desc**: 得到用户意图

    **url**: http(s)://{0}.udicaria.com/intent

    **method**: POST

    **params**:

        <body>:
            bot_id: 机器id(udi/careana)
            user_id: 用户id
            user_message: 用户文本
            hotel_services: 酒店服务列表
            hotel_questions: 固定问答列表
            health_questions: 健康固定问答
            health_products: 健康产品
            health_services: 健康服务

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data: [
                {
                    domain: 话题领域 /酒店服务(hotel_service)/健康服务(health_service)/卡片服务(card_service)/固定问答(fixed_qa)/视频连接(video_link)
                    intent:  意图 report(报告)/product(产品)/service(服务)/data_comparison(数据比较)
                    id: product/service 时返回的id
                    answer: 命中固定问答答案
                }
            ]
            exec_time: 接口后端处理时长
        }
    """
    data = await IntentService.get_user_intent(bot_id.value,
                                               user_id,
                                               user_message,
                                               hotel_services,
                                               hotel_questions,
                                               health_questions,
                                               health_products,
                                               health_services,
                                               dev_id=dev_id,
                                               session=session)

    return json_response(data=data)


@intent_router.post('/intent/all', summary='用户意图(全部)')
@api_common(doc_replace=(('{0}', Config.HTTP_DOC_FIX),))
@exec_duration(add_return=True)
async def get_intent_all(request: Request,
                         bot_id: Role.enums(fixed=Global.count()) = Body(..., title='数字人id'),
                         user_id: str = Body(Role.UDI.value.user_id, title='用户id'),
                         dev_id: str = Body('dev01', title='设备id'),
                         user_message: str = Body(..., title='用户文本'),
                         hotel_services: list[Service] = Body([], title='酒店服务列表'),
                         hotel_questions: list[Question] = Body([], title='酒店固定问答列表'),
                         health_questions: list[Question] = Body([], title='健康固定问答列表'),
                         health_products: list[Product] = Body([], title='产品列表(睡眠监测)'),
                         health_services: list[Service] = Body([], title='服务列表(睡眠监测)'),
                         session: Session = Depends(get_session)):
    """
    **desc**: 得到用户意图(全部)

    **url**: http(s)://{0}.udicaria.com/intent/all

    **method**: POST

    **params**:

        <body>:
            bot_id: 机器id(udi/careana)
            user_id: 用户id
            user_message: 用户文本
            hotel_services: 酒店服务列表
            hotel_questions: 固定问答列表
            health_questions: 健康固定问答
            health_products: 健康产品
            health_services: 健康服务

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data: [
                {
                    domain: 话题领域 /酒店服务(hotel_service)/健康服务(health_service)/卡片服务(card_service)/固定问答(fixed_qa)/视频连接(video_link)
                    intent:  意图 report(报告)/product(产品)/service(服务)/data_comparison(数据比较)
                    id: product/service 时返回的id
                    answer: 命中固定问答答案
                }
            ]
            exec_time: 接口后端处理时长
        }
    """
    data = await IntentService.get_user_intent_all(bot_id.value,
                                                   user_id,
                                                   user_message,
                                                   hotel_services,
                                                   hotel_questions,
                                                   health_questions,
                                                   health_products,
                                                   health_services,
                                                   dev_id=dev_id,
                                                   session=session)

    return json_response(data=data)


@intent_router.post('/intent/model_parameter', summary='用户意图的模型参数')
@api_common(doc_replace=(('{0}', Config.HTTP_DOC_FIX),))
@exec_duration(add_return=True)
async def get_intent_model_parameter(request: Request,
                                     hotel_services: list[Service] = Body([], title='酒店服务列表'),
                                     hotel_questions: list[Question] = Body([], title='酒店固定问答列表'),
                                     health_questions: list[Question] = Body([], title='健康固定问答列表'),
                                     health_products: list[Product] = Body([], title='产品列表(睡眠监测)'),
                                     health_services: list[Service] = Body([], title='服务列表(睡眠监测)')):
    """
    **desc**: 得到用户意图(全部)

    **url**: http(s)://{0}.udicaria.com/intent/model_parameter

    **method**: POST

    **params**:

        <body>:
            hotel_services: 酒店服务列表
            hotel_questions: 固定问答列表
            health_questions: 健康固定问答
            health_products: 健康产品
            health_services: 健康服务

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data: [
                {
                    domain: 话题领域 /酒店服务(hotel_service)/健康服务(health_service)/卡片服务(card_service)/固定问答(fixed_qa)/视频连接(video_link)
                    intent:  意图 report(报告)/product(产品)/service(服务)/data_comparison(数据比较)
                    id: product/service 时返回的id
                    answer: 命中固定问答答案
                }
            ]
            exec_time: 接口后端处理时长
        }
    """
    data = await IntentService.get_model_parameter(hotel_services,
                                                   hotel_questions,
                                                   health_questions,
                                                   health_products,
                                                   health_services)

    return json_response(data=data)


@intent_router.get('/intent/user_chat_memories', summary='用户记忆')
@api_common(doc_replace=(('{0}', Config.HTTP_DOC_FIX),))
@exec_duration(add_return=True)
async def get_user_chats(request: Request,
                         user_id: str = Query(..., title='用户id'),
                         chat_count: int = Body(2, title='查询问答记录id', description='默认2')):
    """
    **desc**: 用户意图历史记忆

    **url**: http(s)://{0}.udicaria.com/intent/user_chat_memories

    **method**: POST

    **params**:

        <body>:
            user_id: 用户id(必传)

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data: [

            ]
            exec_time: 接口后端处理时长
        }
    """
    user_memories = IntentService.get_user_chats(user_id, chat_count)

    return json_response(data=user_memories)


@intent_router.get('/intent/chat/list_page', summary='意图日志')
@api_common(doc_replace=(('{0}', Config.HTTP_DOC_FIX),))
@exec_duration(add_return=True)
async def get_intent_chat_list_page(request: Request,
                                    dev_id: str = Query('', title='设备id'),
                                    bot_id: str = Query('', title='数字人id'),
                                    user_id: str = Query('', title='登录用户id'),
                                    start_time: generate_validator(DateTimeStr, blank_enable=True) = Query('', title='开始时间'),
                                    end_time: generate_validator(DateTimeStr, blank_enable=True) = Query('', title='结束时间'),
                                    page: int = Query(1, title='第几页', description='默认1'),
                                    page_size: int = Query(20, title='条数', description='每页显示的条数'),
                                    session: Session = Depends(get_session)):
    """
    **desc**: 意图日志

    **url**: http(s)://{0}.udicaria.com/intent/chat/list_page

    **method**: GET

    **params**:

        <query>:

            dev_id: 设备id
            bot_id: 数字人id
            user_id: 账户id
            user_message: 用户信息
            bot_message: 数字人信息
            start_time: 开始时间(%Y-%m-%d %H:%M:%S)
            end_time: 结束时间(%Y-%m-%d %H:%M:%S)

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data: {
                num: 数据总条数
                items: [
                    {
                        dev_id: 设备id
                        bot_id: 数字人id
                        user_id: 账户id
                        user_message: 用户信息
                        bot_message: 数字人信息
                        detail: 推理详情
                    }
                ]
            }
            exec_time: 接口后端处理时长
        }
    """
    def _set_qr(qr):
        if dev_id:
            qr = qr.filter(Chat.dev_id == dev_id)
        if bot_id:
            qr = qr.filter(Chat.bot_id == bot_id)
        if user_id:
            qr = qr.filter(Chat.user_id == user_id)
        if start_time:
            qr = qr.filter(Chat.create_time >= start_time)
        if end_time:
            qr = qr.filter(Chat.create_time <= end_time)

        return qr

    # num
    query = session.query(func.count())
    query = _set_qr(query)
    num = query.scalar()

    # items
    query = session.query(Chat)
    query = _set_qr(query)
    query = query.order_by(Chat.id.desc()).offset((page - 1) * page_size).limit(page_size)
    data = query.all()

    ret_data = {
        'num': num,
        'items': [v.dict() for v in data]
    }

    return json_response(data=ret_data)




